package com.movie.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.movie.bean.*;
import com.movie.bean.vo.TicketOrderQueryVO;
import com.movie.common.HttpResult;
import com.movie.mapper.*;
import com.movie.service.MovieService;
import com.movie.utils.FileUpload;
import com.movie.utils.PageUtil;
import com.obs.services.ObsClient;
import com.obs.services.model.PutObjectRequest;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class MovieServiceImpl implements MovieService {
    @Autowired
    private FileUpload fileUpload;

    @Autowired
    private MovieMapper movieMapper;

    @Autowired
    private FavorityMapper favorityMapper;

    @Autowired
    private TicketMapper ticketMapper;

    @Autowired
    private RechargeMapper rechargeMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private final static DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Override
    public List<Integer> getSeat(int sid) {
        List<Integer> seats = new ArrayList<>();
        LinkedHashSet<String> keys = (LinkedHashSet<String>) redisTemplate.keys("session:" + sid + ":*:seat:*");
        for (String key : keys) {
            Integer seat = (Integer) redisTemplate.opsForValue().get(key);
            seats.add(seat);
        }
        seats.addAll(movieMapper.getSeat(sid));
        return seats;
    }

    @Override
    public Session getSession(int sid) {
        return movieMapper.getSession(sid);
    }

    @Override
    @Transactional //添加事务
    public void buyTicket(List<Ticket> list) {//插入购买的电影票信息
        movieMapper.buyTicket(list);
    }

    @Override
    public List<Ticket> checkTicket(List<Ticket> tickets) {
        return movieMapper.checkTicket(tickets);
    }

    @Override
    public List<Movie> getAllMovieList() {
        return movieMapper.getAllMovieList();
    }

    @Override
    public List<Session> getMovieSessionList(int mid) {
        return movieMapper.getMovieSessionList(mid);
    }

    @Override
    public Page<Movie> getMovieListPageInfo(int pageNum, int pageSize) {
        List<Movie> list = movieMapper.getAllMovieList();
        return PageUtil.PaginatedResult(list, pageNum, pageSize);
    }

    @Override
    public void delMovieByMid(int mid) {
        movieMapper.delMovieByMid(mid);
    }

    @Override
    public void updateMovie(Movie movie, MultipartFile img) {
        if (img != null) {
            String fileName = fileUpload.upload(img);
            movie.setMimg(fileName);
        }
        if (movie.getId() != null) movieMapper.updateMovie(movie);
        else movieMapper.insert(movie);
    }

    @Override
    public void addMovieSession(Session session) {
        movieMapper.addMovieSession(session);
    }

    @Override
    public long gerTotalMoney() {
        return movieMapper.gerTotalMoney();
    }

    public List<MovieRank> getMovieRankList() {
        return movieMapper.getMovieRankList();
    }

    @Override
    public int getUserCount() {
        return movieMapper.getUserCount();
    }

    @Override
    public int getAdminCount() {
        return movieMapper.getAdminCount();
    }

    @Override
    public int getMovieCount() {
        return movieMapper.getMovieCount();
    }

    @Override
    public int getTicketCount() {
        return movieMapper.getTicketCount();
    }

    @Override
    public void addSlideImg(int mid, String imgUrl, String createTime) {
        movieMapper.addSlideImg(mid, imgUrl, createTime);
    }

    @Override
    public List<SlideImg> getSlideImgList() {
        return movieMapper.getSlideImgList();
    }

    @Override
    public List<Movie> getMovieListByKeyWord(String keyWord) {
        return movieMapper.getMovieListByKeyWord(keyWord);
    }


    @Override
    public Page<TicketOrder> getTicketOrderList(int pageNum, int pageSize) {
        List<TicketOrder> list = movieMapper.getTicketOrderList();
        return PageUtil.PaginatedResult(list, pageNum, pageSize);
    }

    @Override
    public Page<TicketOrder> getTicketOrderByKeyWord(TicketOrderQueryVO ticketOrderQueryVO) {
        List<TicketOrder> list = movieMapper.getTicketOrderByKeyWord(ticketOrderQueryVO);
        return PageUtil.PaginatedResult(list, ticketOrderQueryVO.getPageNo(), ticketOrderQueryVO.getPageSize());
    }

    @Override
    public void delSlideImgById(int id) {
        movieMapper.delSlideImgById(id);
    }

    @Override
    public List<Movie> getHotMovieList() {
        return movieMapper.getHotMovieList();
    }

    @Override
    public List<Movie> getHotMovieByKeyWord(String mclass, String mnation) {
        return movieMapper.getHotMovieByKeyWord(mclass, mnation);
    }

    @Override
    public List<Movie> getMovieSearchResult(String searchType, String searchContent) {
        return movieMapper.getMovieSearchResult(searchType, searchContent);
    }

    @Override
    public Movie getMovieById(int mid) {
        return movieMapper.getMovieById(mid);
    }

    @Override
    public PageInfo<Favorite> getLikeMovie(Integer id, Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        List<Favorite> likeMovie = favorityMapper.getLikeMovie(id);
        PageInfo<Favorite> pageInfo = new PageInfo<>(likeMovie);
        return pageInfo;
    }

    @Override
    public List<TicketOrder> getTicketOrderByStatus(Integer uid, Integer status, Integer pageNo, Integer pageSize) {

        return ticketMapper.getTicketOrders(uid, status);
    }

    @Override
    public Long getRechargeCount() {
        return rechargeMapper.selectTotalMoney();
    }

    @Override
    public Map<String, Double> getRechargeRecent() {
        LocalDate endTime = LocalDate.now();
        LocalDate startTime = endTime.minusDays(6);
        List<Recharge> list = rechargeMapper.selectList(new QueryWrapper<Recharge>().between("create_time", DTF.format(startTime), DTF.format(endTime.plusDays(1))));
        System.out.println(list);
        int count = 0;
        Map<String, Double> map = new HashMap<>();
        while (count < 7) {
            LocalDate date = endTime.minusDays(count);
            double sum = list.stream().filter(i -> {
                Date createTime = i.getCreateTime();
                Instant instant = createTime.toInstant();
                ZoneId zoneId = ZoneId.systemDefault();
                LocalDate localDate = instant.atZone(zoneId).toLocalDate();
                return localDate.equals(date);
            }).mapToDouble(Recharge::getMoney).sum();
            map.put(DTF.format(date), sum);
            count++;
        }
        return map;
    }

    @Override
    public TicketOrder selectOrder(String number) {
        return ticketMapper.selectOrder(number);
    }

    @Override
    @Transactional
    public void returnTicket(String number, Integer uid) {
        Set<String> keys = redisTemplate.keys("*:" + number + ":*");
        redisTemplate.delete(keys);
        TicketOrder ticketOrder = ticketMapper.selectOrder(number);
        if (ticketOrder == null) throw new RuntimeException();
        int total = ticketOrder.getTotal();
        userMapper.updateBalance(total, uid);
        ticketMapper.refund(number);
    }

    @Override
    public SlideImg slideImgDetail(Integer id) {
        return movieMapper.slideImgDetail(id);
    }

    @Override
    public void updateSlideImg(int mid, String fileName, Integer id) {
        movieMapper.updateSlideImg(mid, fileName, id);
    }

    @Override
    public void updateSlideImg1(int mid, Integer id) {
        movieMapper.updateSlideImg1(mid, id);
    }
}
